{ open Parser }

let letter = ['a'-'z' 'A'-'Z']
let digit = ['0'-'9']
let punc = ['~' '`' '!' '@' '#' '$' '%' '^' '&' '*' '(' ')' '-' '+' '=' ','
'.' '?' '/' '<' '>' ':' '''  ';' '{' '}' '[' ']' '|' ' ']
let escape = ["\\n" "\\t" "\\"" "\\\"]

let intType = '-'? digit+
let doubleType = '-'? digit+ '.' digit*
let boolType = ["true" "false"]
let stringType = '"' (digit|letter|punc|escape)* '"'
let cardType = '$'['2'-'9' "10" 'J' 'Q' 'K' 'A']['C' 'D' 'H' 'S']
let rec listType = function
	'['((intType|doubleType|boolType|stringType|cardType|listType) ',')*
		 (intType|doubleType|boolType|stringType|cardType|listType) ']'
| '[' ']' 

rule token = parse
  [' ' '\t' '\r' '\n'] { token lexbuf } (* Whitespace *)
| "/*"     { comment lexbuf }           (* Comments *)
| '('      { LPAREN }
| ')'      { RPAREN }
| '{'      { LBRACE }
| '}'      { RBRACE }
| ';'      { SEMI }
| ','      { COMMA }
| '+'      { PLUS }
| '-'      { MINUS }
| '*'      { TIMES }
| '/'      { DIVIDE }
| '='      { ASSIGN }
| "=="     { EQ }
| "!="     { NEQ }
| '<'      { LT }
| "<="     { LEQ }
| ">"      { GT }
| ">="     { GEQ }
| "if"     { IF }
| "else"   { ELSE }
| "for"    { FOR }
| "while"  { WHILE }
| "return" { RETURN }
| intType as lxm { INT(int_of_string lxm) }
| doubleType as lxm { DOUBLE(lxm) }
| boolType as lxm { BOOL(lxm) }
| stringType as lxm { STRING(lxm) }
| cardType as lxm { CARD(lxm) }
| listType as lxm { LIST(lxm) }


| ['a'-'z' 'A'-'Z']['a'-'z' 'A'-'Z' '0'-'9' '_']* as lxm { ID(lxm) }
| eof { EOF }
| _ as char { raise (Failure("illegal character " ^ Char.escaped char)) }

and comment = parse
  "*/" { token lexbuf }
| _    { comment lexbuf }